package com.raise.drive.commons.captcha;

import com.octo.captcha.component.image.fontgenerator.RandomFontGenerator;

import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;

public class MyRandomFontGenerator extends RandomFontGenerator {

    public MyRandomFontGenerator(Integer integer, Integer integer1, Font[] fonts) {
        super(integer, integer1, fonts);
    }

    public MyRandomFontGenerator(Integer minFontSize, Integer maxFontSize) {
        super(minFontSize, maxFontSize);
    }

    public Font getFont() {
        //defaultFonts are initialized one time, cause static
        if (defaultFonts == null) {
            // we cache a lot of decisions about ttf -- do this as little as possible
            synchronized (RandomFontGenerator.class) {
                if (defaultFonts == null) {
                    defaultFonts = initializeFontsWithNoExceptions(GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts());
                }
            }
        }

        if (fonts == null) {
            fonts = defaultFonts;
        }

        Font font = (Font) fonts.get(myRandom.nextInt(fonts.size()));

        int plus = 0;
        if (getMaxFontSize() - getMinFontSize() > 0) {
            plus = Math.abs(myRandom.nextInt(getMaxFontSize()
                    - getMinFontSize()));
        }

        return new Font(font.getFontName(),
                STYLES[myRandom.nextInt(STYLES.length)],
                getMinFontSize() + plus);
    }

    /**
     * Create an array of ttf that is known to properly represent all the characters in requiredCharacters.
     *
     * @param uncheckFonts an array of fonts
     * @return array of ttf
     * @see #requiredCharacters
     */
    private java.util.List initializeFontsWithNoExceptions(Font[] uncheckFonts) {

        // get a copy of the ttf
        // NB: be careful with this first array! -- the graphics environment obligingly
        // provides a pointer into its internal font array.

        java.util.List<Font> goodFonts = new ArrayList<Font>(uncheckFonts.length);
        // add copy of copy of list of ttf because of asList's special class and also because
        // of the graphics environment's internal point
        goodFonts.addAll(Arrays.asList(uncheckFonts));

        // Iterate through all ttf, remove the bad ones
        for (Iterator iter = goodFonts.iterator(); iter.hasNext();) {
            Font f = (Font) iter.next();

            // a font is removed if it cannot display the characters we need.

            for (int i = 0; i < getRequiredCharacters().length(); i++) {
                boolean canDisplay = false;

                try {
                    canDisplay = f.canDisplay(getRequiredCharacters().charAt(i));
                } catch (Throwable e) {
                }

                if (!canDisplay) {
                    iter.remove();
                    break;
                }
            }

            // a font is also removed if it is prefixed by a known-bad name
            for (int i = 0; i < getBadFontNamePrefixes().length; i++) {
                if (f.getName().startsWith(getBadFontNamePrefixes()[i])) {
                    iter.remove();
                    break;
                }
            }
        }

        return goodFonts;
    }

}
